#include "serwerinfo.h"

SerwerInfo::SerwerInfo(QString ip,int port,int localport, int id):
        QThread(),
        id(id),
        ip(ip),
        port(port),
        localport(localport),
        graczy(0),
        max_graczy(0),
        activeRcon(false),
        activeSerwer(false)
{

    //init_serwer();
    init_strona1();
    init_strona2();
    init_socket();
    init_players_table_basic();

    //czas_gry->start();
    send_datagram(A2S_INFO);
    send_datagram(A2S_PLAYER);
    send_datagram(A2S_RULES);
    //send_datagram(A2S_RULES);

    //send_datagram(A2S_RULES);



    //
    QTimer *second_plus=new QTimer();
    second_plus->start(1000);
    connect(second_plus,SIGNAL(timeout()),this,SLOT(time_players_basic_plus()));

    QTimer *one=new QTimer();
    connect(one,SIGNAL(timeout()),this,SLOT(send_a2s_player_info()));
    one->start(5000);

    QTimer *two=new QTimer();
    //connect(two,SIGNAL(timeout()),this,SLOT(testslo()));

    two->start(5000);
    QList <QString> lissta;
    lissta.append(QString("0"));
    lissta.append(QString("1"));
    lissta.append(QString("2"));
    lissta.append(QString("3"));

    //lissta.removeAt(2);
    bro->setText(lissta.at(3));

}

void SerwerInfo::init_strona1()
{
    this->bro=new QTextBrowser();
    this->players_table_basic=new QTableWidget();
    this->LabelInfo=new SerwerLabelInfo();
    QString temp("");
    this->LabelInfo->SerwerIP->setText(ip+":"+temp.setNum(port));
}

void SerwerInfo::init_strona2()
{
    this->basic_player_graph=new players_graph();
    this->basic_player_graph->set_players(graczy,max_graczy);

}

void SerwerInfo::init_strona3()
{
    console_output=new QTextBrowser();
    console_input=new QLineEdit();
    send=new QPushButton("Send");
    clear=new QPushButton("Clear");

    connect(clear,SIGNAL(clicked()),this,SLOT(clear_console()));
    connect(send,SIGNAL(clicked()),this,SLOT(send_rcon_slot()));

}

void SerwerInfo::init_socket()
{
    socket_udp=new QUdpSocket(this);
    socket_udp->bind(localport);
    connect(socket_udp,SIGNAL(readyRead()),this,SLOT(odbierz_datagram()));

}

void SerwerInfo::init_players_table_basic()
{
    players_table_basic->setFixedWidth(400);
    players_table_basic->setFixedHeight(350);
    players_table_basic->setColumnCount(3);
    players_table_basic->setRowCount(1);

    players_table_basic->setColumnWidth(0,200);
    players_table_basic->setColumnWidth(1,95);
    players_table_basic->setColumnWidth(2,95);
    //players_table_basic->adjustSize();

    QStringList bng;
    bng.append("Nick");
    bng.append("Frags");
    bng.append("Time");
    players_table_basic->setHorizontalHeaderLabels(bng);;
    players_table_basic->setRowCount(0);
}

void SerwerInfo::send_datagram(QString zapytanie)
{

    QByteArray datagram;
    datagram.append(zapytanie);
    bro->append(QString(datagram.data()));
    socket_udp->writeDatagram(datagram.data(),datagram.size(),QHostAddress(ip),port);
    emit wyslany_pakiet();

}

void SerwerInfo::time_players_basic_plus()
{
    QString czas("");
    QTime temp;
    QTableWidgetItem *item;
    for(int i=0;i<players_table_basic->rowCount();i++)
    {
        czas=players_table_basic->item(i,2)->text();
        temp=QTime::fromString(czas,"mm:ss");
        temp=temp.addSecs(1);
        //czas=temp.toString("mm:ss");
        item=new QTableWidgetItem(temp.toString("mm:ss"));
        players_table_basic->setItem(i,2,item);


    }
}

void SerwerInfo::send_a2s_player_info()
{
    send_datagram(A2S_PLAYER);
    send_datagram(A2S_INFO);

}

void SerwerInfo::run()
{
    exec();

}

void SerwerInfo::testslo()
{
    max_graczy=0;
};

void SerwerInfo::odbierz_datagram()
{
    while(socket_udp->hasPendingDatagrams())
    {
        if(!activeSerwer)
        {
            activeSerwer=true;
            emit serwer_status(activeSerwer,activeRcon);
        }
        QByteArray datagram;
        datagram.resize(socket_udp->pendingDatagramSize());
        QHostAddress sender;
        quint16 port;

        socket_udp->readDatagram(datagram.data(),datagram.size(),&sender,&port);

        emit odebrany_pakiet();
        bro->append(QString(datagram.data()));
       /* QString bongo("");
        for(int i=0;i<datagram.size();i++)
        {
            if(datagram.at(i)=='\0') bongo+='\n';
            else bongo+=datagram.at(i);
        }*/

        przetworz_datagram(datagram);
    }

}

void SerwerInfo::przetworz_datagram(QByteArray &datagram)
{

    if(datagram.at(4)==A2A_PING_R) parsuj_datagram(datagram, A2A_PING_REPLY);
    else if(datagram.at(0)==A2S_MULTI_R) parsuj_a2s_multi_reply(datagram);//ok
    else if(datagram.at(4)==A2S_INFO_R) parsuj_a2s_info_reply(datagram);//ok
    else if(datagram.at(4)==A2S_INFO_R2) parsuj_a2s_info_reply2(datagram);//ok
    else if(datagram.at(4)==A2S_PLAYER_R) parsuj_a2s_player_reply(datagram);
    else if(datagram.at(4)==A2S_RULES_R) parsuj_a2s_rules_reply(datagram);
    else if(datagram.at(4)==A2S_SERVERQUERY_GETCHALLENGE_R)
    {
        parsuj_datagram(datagram,A2S_SERVERQUERY_GETCHALLENGE_REPLY);
    }
    else if(datagram.at(4)=='c' and datagram.at(14)=='r')
    {
        parsuj_rcon_challenge_rcon_reply(datagram);
    }
    else if(datagram.at(4)==RCON_R) parsuj_rcon(datagram);
    else  debug_parse(datagram);


}

void SerwerInfo::parsuj_rcon(QByteArray &datagram)
{
    datagram.remove(0,5);
    if(!activeRcon)
    {
        if(datagram.at(0)=='d' and datagram.at(1)=='o' and
           datagram.at(2)=='b' and datagram.at(3)=='r' and
           datagram.at(4)=='e')
        {
            bro->setText(bro->toPlainText()+"hyper gitara ");
            activeRcon=true;
            emit rcon_valid(id,true);
            emit serwer_status(activeSerwer,activeRcon);
        }
        else if(datagram.at(0)=='B' and datagram.at(1)=='a' and
                datagram.at(2)=='d' and datagram.at(3)==' ' and
                datagram.at(4)=='r')
        {
            bro->setText(bro->toPlainText()+"lipa ");
            activeRcon=false;
            emit rcon_valid(id,false);
        }
    }
    else
    {
        QString ww(datagram);
        //bro->setText(bro->toPlainText()+ww);
        //console_output->setText(console_output->toPlainText()+ww+"\n");
        console_output->append(ww);


    }
}

void SerwerInfo::parsuj_datagram(QByteArray &datagram, int typ)
{
    QString a("");
    for(int i=0;i<datagram.size();i++)
    {
        if(datagram.at(i)=='\0')  a+="\n";
        else a+=datagram.at(i);
    }
    bro->setText(a);
}

void SerwerInfo::parsuj_a2s_info_reply(QByteArray &datagram)
{
    datagram.remove(0,5);
    //QString all("");
    QString temp("");
    temp=datagram.data();
    //all=all+"ip "+temp+'\n';
    datagram.remove(0,temp.length()+1);
    //SerwerName->setText(temp);
    temp=datagram.data();
    //all=all+"name "+temp+'\n';
    LabelInfo->SerwerName->setText(temp);
    datagram.remove(0,temp.length()+1);
    temp=datagram.data();
    //all=all+"map "+temp+'\n';
    LabelInfo->SerwerMap->setText(temp);
    datagram.remove(0,temp.size()+1);
    temp=datagram.data();
    //all=all+"dir "+temp+'\n';
    LabelInfo->SerwerDir->setText(temp);
    datagram.remove(0,temp.size()+1);
    temp=datagram.data();
    //all=all+"game "+temp+'\n';
    LabelInfo->SerwerGame->setText(temp);
    datagram.remove(0,temp.size()+1);
    //temp.setNum(datagram.at(0));
    LabelInfo->SerwerPlayers->setText(QString::number(datagram.at(0)));
    //temp.setNum(datagram.at(1));
    LabelInfo->SerwerMaxPlayers->setText(QString::number(datagram.at(1)));
    max_graczy=QString::number(datagram.at(1)).toInt();
    //temp.setNum(datagram.at(2));
    LabelInfo->SerwerProtocol->setText(QString::number(datagram.at(2)));
    temp=datagram.at(3);
    if(temp=="l") LabelInfo->SerwerType->setText("Listen");
    else if(temp=="d") LabelInfo->SerwerType->setText("Dedicated");
    else if(temp=="p") LabelInfo->SerwerType->setText("HLTV");
    //temp=datagram.at(4);
    LabelInfo->SerwerOS->setText(QString(datagram.at(4))=="w"?"Windows":"Linux");
    //temp=datagram.at(5);
    LabelInfo->SerwerPassword->setText(QString(datagram.at(5))=="1"?"Tak":"Nie");

    datagram.remove(0,6);

    //bro->setText(bro->toPlainText()+"[gite]"+temp.setNum(datagram.size())+"[ggg]\n");
    //temp.setNum(datagram.at(0));
    //datagram.remove(0,1);

    if(QString(datagram.at(0))=="1")
    {
        datagram.remove(0,1);
        //bro->append(bro->toPlainText()+"is MOd: "+temp+"\n");
        temp=datagram.data();
        //bro->append(bro->toPlainText()+"Stringu: "+temp+"\n");
        datagram.remove(0,temp.length()+1);
        temp=datagram.data();
        //bro->append(bro->toPlainText()+"String2: "+temp+"\n");
        datagram.remove(0,temp.length()+2);\
        QByteArray longd(datagram.data(),4);
        datagram.remove(0,4);
        //bro->append(bro->toPlainText()+"long1: "+temp.setNum(bng)+"\n");
        datagram.remove(0,4);
        //bro->append(bro->toPlainText()+"long2: "+temp.setNum(bng2)+"\n");
        temp.setNum(datagram.at(0));
        //bro->append(bro->toPlainText()+"svonly: "+temp+"\n");
        temp.setNum(datagram.at(1));
        //bro->append(bro->toPlainText()+"Cidll: "+temp+"\n");
        datagram.remove(0,2);

    }
    else datagram.remove(0,1);


    //temp.setNum(datagram.at(0));
    LabelInfo->SerwerSecure->setText((QString::number(datagram.at(0))=="1"?"Tak":"Nie"));
    //bro->setText(bro->toPlainText()+"secure: "+(temp=="1"?"Tak":"Nie")+"\n");
   // temp.setNum(datagram.at(1));
    LabelInfo->SerwerBots->setText(QString::number(datagram.at(1)));
    //bro->setText(bro->toPlainText()+"Boty: "+temp+"\n");

    if(!activeRcon) emit serwer_valid(id,LabelInfo->SerwerName->text());
}

void SerwerInfo::parsuj_a2s_info_reply2(QByteArray &datagram)
{
    datagram.remove(0,5);
    //QString all("");
    QString temp("");
    //temp.setNum(datagram.at(0));
    //SerwerProtocol->setText(temp);
    LabelInfo->SerwerProtocol->setText(LabelInfo->SerwerProtocol->text()=="47"?"47/"+QString::number(datagram.at(0)):QString::number(datagram.at(0)));
    datagram.remove(0,1);
    temp=datagram.data();
    LabelInfo->SerwerName->setText(temp);
    datagram.remove(0,temp.length()+1);
    temp=datagram.data();
    LabelInfo->SerwerMap->setText(temp);
    datagram.remove(0,temp.length()+1);
    temp=datagram.data();
    LabelInfo->SerwerDir->setText(temp);
    datagram.remove(0,temp.length()+1);
    temp=datagram.data();
    LabelInfo->SerwerGame->setText(temp);
    datagram.remove(0,temp.length()+3); //app_id nie jest potrzebne
    //temp.setNum(datagram.at(0));
    LabelInfo->SerwerPlayers->setText(QString::number(datagram.at(0)));
    temp.setNum(datagram.at(1));
    max_graczy=temp.toInt();
    LabelInfo->SerwerMaxPlayers->setText(temp);
    //temp.setNum(datagram.at(2));
    LabelInfo->SerwerBots->setText(QString::number(datagram.at(2)));
    temp=datagram.at(3);
    if(temp=="l") LabelInfo->SerwerType->setText("Listen");
    else if(temp=="d") LabelInfo->SerwerType->setText("Dedicated");
    else if(temp=="p") LabelInfo->SerwerType->setText("HLTV");
    //temp=datagram.at(4);
    LabelInfo->SerwerOS->setText(QString(datagram.at(4))=="w"?"Windowsx":"Linux");
    //temp=datagram.at(5);
    LabelInfo->SerwerPassword->setText(QString(datagram.at(5))=="1"?"Tak":"Nie");
    //temp=datagram.at(6);
    LabelInfo->SerwerSecure->setText((QString(datagram.at(6))=="1"?"Tak":"Nie"));

    if(!activeRcon) emit serwer_valid(id,LabelInfo->SerwerName->text());

}

void SerwerInfo::parsuj_a2s_multi_reply(QByteArray &datagram)
{
    datagram.remove(0,4);
    QByteArray long_id(datagram.data(),4);
    int *ids=(int*)long_id.data();
    int id=*ids;
    bro->setText("id"+QString::number(id)+"id"+"size"+QString::number(Multi.size())+"sss");
    char ilosc(datagram.at(4));
    char numer(ilosc);

    ilosc=ilosc<<4;
    ilosc=ilosc>>4;

    numer=numer>>4;

    QString a("");
    QString b("");
    datagram.remove(0,5);

    //bro->setText(bro->toPlainText()+"["+datagram.at(0)+"]\n");


    bool is_added=false;
    int num;

    for(int i=Multi.size();i>0 and i>Multi.size()-5;i--)
    {
        if(Multi[i-1]->id==id)
        {
            is_added=true;
            num=i-1;
            break;
        }
    }

    if(is_added)
    {
        Multi[num]->dodaj(numer,datagram);
        bro->setText(bro->toPlainText()+"juz byl\n");
        if(Multi[num]->czy_caly)
        {
            bro->setText(bro->toPlainText()+"juz caly\n");
            QByteArray caly=Multi[num]->zwroc_caly_datagram();
            przetworz_datagram(caly);

        }

    }
    else
    {
        MultiDatagram *nowy=new MultiDatagram(id,ilosc,numer,datagram);
        Multi.append(nowy);
        bro->setText(bro->toPlainText()+"nowy\n");

    }

    //bro->setText(bro->toPlainText()+"ilosc: "+a.setNum(ilosc)+"\nnumer "+b.setNum(numer)+"[>"+"<]\n");

}

void SerwerInfo::parsuj_a2s_rules_reply(QByteArray &datagram)
{
    QString b("");
    for(int i=0;i<datagram.size();i++)
    {
        if(datagram.at(i)=='\0') b+="\n";
        else b+=datagram.at(i);
    }
    bro->setText(bro->toPlainText()+"\n\nD>"+b);
}

void SerwerInfo::parsuj_a2s_player_reply(QByteArray &datagram)
{
    QString a("");
    QString temp("");
    int ile_graczy=datagram.at(5);
    temp.setNum(ile_graczy);
    datagram.remove(0,6);
    //a="ilosc "+temp+"\n";
    QTime czasy;
    graczy=ile_graczy;
    players_table_basic->setRowCount(ile_graczy);
    for(int i=0;i<ile_graczy;i++)
    {
        QString id("");
        id.setNum(datagram.at(0));
        datagram.remove(0,1);
        QString nazwa("");
        nazwa=datagram.data();

        QTableWidgetItem *idw= new QTableWidgetItem();
        idw->setText(nazwa);
        players_table_basic->setItem(i,0,idw);

        datagram.remove(0,nazwa.length()+1);
        QByteArray tfrag(datagram.data(),4);
        long *fragi=(long*)tfrag.data();
        //QString frags("");
        //frags.setNum(*fragi);

        QTableWidgetItem *fragw=new QTableWidgetItem(QString::number(*fragi));
        players_table_basic->setItem(i,1,fragw);

        datagram.remove(0,4);
        QByteArray tczas(datagram.data(),4);
        datagram.remove(0,4);

        float *czas=(float*)tczas.data();
        //QString time("");
        //time.setNum(*czas);

        int czas_int=(int)*czas;
        int godziny=czas_int/3600;
        int sekundy=czas_int%3600;
        int minuty=sekundy/60;
        sekundy=sekundy%60;

        czasy=QTime(godziny,minuty,sekundy,0);
        //QString czasw;
        //czasw=czasy.toString("mm:ss");
        QTableWidgetItem *czassw=new QTableWidgetItem();
        czassw->setText(czasy.toString("mm:ss"));
        players_table_basic->setItem(i,2,czassw);
        //czassw->
    }

    //bro->setText(a);

}

void SerwerInfo::debug_parse(QByteArray &datagram)
{
    QString t("");
    for(int i=0;i<datagram.size();i++)
    {
        if(datagram.at(i)=='\0') t+="\n";
        else t+=datagram.at(i);
    }
    bro->setText(bro->toPlainText()+"->"+t+"<-\n");
}

void SerwerInfo::parsuj_rcon_challenge_rcon_reply(QByteArray &datagram)
{
    QString t("");
    for(int i=0;i<datagram.size();i++)
    {
        if(datagram.at(i)==' ') t="";
        else if(datagram.at(i)=='\n');
        else if(datagram.at(i)=='\0');

        else t+=datagram.at(i);
    }
    //rcon_challenge.length();
    rcon_challenge=t;
    bro->setText(bro->toPlainText()+"->"+rcon_challenge+"<-\n");
    send_datagram(RCON_RCON_LOGIN+rcon_challenge+" \""+rcon_password+"\" echo dobre");


}

void SerwerInfo::clear_console()
{
    console_output->setText("");
}

void SerwerInfo::send_rcon_slot()
{
    QString data("");
    data=console_input->text();
    send_rcon_datagram(data);
}

void SerwerInfo::send_rcon_datagram(QString data)
{
    //<font color=red > </font>
    //console_output->setText(console_output->toPlainText()+"<font color=red >"+data+"</font>"+"\n");
    console_output->append(":. RCON .:  "+data);
    send_datagram(RCON_RCON_LOGIN+rcon_challenge+" \""+rcon_password+"\" "+data);

}

void SerwerInfo::serwer_try_exit()
{
    emit serwer_exit(id);
}
